import SwiftUI
import SceneKit
import AppKit
import AVFoundation
import SpriteKit
import AVKit

@main
struct ThreeDAlbumApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .windowStyle(.hiddenTitleBar)
    }
}

// 通知扩展
extension Notification.Name {
    static let mediaSelected = Notification.Name("mediaSelected")
    static let videoPlaybackCompleted = Notification.Name("videoPlaybackCompleted")
    static let startARSlideShow = Notification.Name("startARSlideShow")
}

// 全屏媒体详情视图
struct MediaDetailView: View {
    let media: AlbumPhoto
    @Binding var isPresented: AlbumPhoto?
    @State private var scale: CGFloat = 1.0
    @State private var lastScale: CGFloat = 1.0
    @State private var player: AVPlayer?
    @State private var timer: Timer?
    
    var body: some View {
        VStack {
            HStack {
                Spacer()
                Button("关闭") {
                    isPresented = nil
                }
                .padding()
            }
            
            if media.imageName.hasSuffix(".mov") || media.imageName.hasSuffix(".mp4") || 
               media.imageName.hasSuffix(".avi") || media.imageName.hasSuffix(".m4v") {
                // 自定义视频播放器视图
                VideoPlayerView(player: $player, mediaPath: media.imageName)
                    .aspectRatio(contentMode: .fit)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .scaleEffect(scale)
                    .gesture(MagnificationGesture()
                        .onChanged { value in
                            let delta = value / lastScale
                            lastScale = value
                            scale = min(max(scale * delta, 0.5), 3.0)
                        }
                        .onEnded { _ in
                            lastScale = 1.0
                        }
                    )
                    .onAppear {
                        setupVideoPlayer()
                    }
            } else {
                // 图片查看器
                if let image = NSImage(contentsOfFile: media.imageName) {
                    Image(nsImage: image)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                        .scaleEffect(scale)
                        .gesture(MagnificationGesture()
                            .onChanged { value in
                                let delta = value / lastScale
                                lastScale = value
                                scale = min(max(scale * delta, 0.5), 3.0)
                            }
                            .onEnded { _ in
                                lastScale = 1.0
                            }
                        )
                } else {
                    Text("无法加载图片")
                        .font(.largeTitle)
                }
            }
        }
        .padding()
        .frame(width: 800, height: 600)
        .onAppear {
            // 如果是图片，设置2秒后自动关闭
            if !(media.imageName.hasSuffix(".mov") || media.imageName.hasSuffix(".mp4") || 
                 media.imageName.hasSuffix(".avi") || media.imageName.hasSuffix(".m4v")) {
                timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) { _ in
                    isPresented = nil
                }
            }
        }
        .onDisappear {
            timer?.invalidate()
            player?.pause()
            player = nil
        }
    }
    
    private func setupVideoPlayer() {
        player = AVPlayer(url: URL(fileURLWithPath: media.imageName))
        
        // 监听视频播放完成
        NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, 
                                               object: player?.currentItem, 
                                               queue: .main) { _ in
            // 视频播放完成后自动关闭
            isPresented = nil
        }
        
        player?.play()
        
        // 视频播放时自动缩放屏幕
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            withAnimation(.easeInOut(duration: 0.5)) {
                scale = 1.2 // 自动放大到1.2倍
            }
        }
    }
}

// 自定义视频播放器视图（避免VideoPlayer的编译问题）
struct VideoPlayerView: NSViewRepresentable {
    @Binding var player: AVPlayer?
    let mediaPath: String
    
    func makeNSView(context: Context) -> AVPlayerView {
        let playerView = AVPlayerView()
        playerView.player = AVPlayer(url: URL(fileURLWithPath: mediaPath))
        player = playerView.player
        
        // 监听视频播放完成
        NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, 
                                               object: player?.currentItem, 
                                               queue: .main) { _ in
            // 视频播放完成后自动关闭
            NotificationCenter.default.post(name: .videoPlaybackCompleted, object: nil)
        }
        
        player?.play()
        return playerView
    }
    
    func updateNSView(_ nsView: AVPlayerView, context: Context) {
        // 更新视图
    }
}

struct AlbumPhoto: Identifiable {
    let id = UUID()
    let imageName: String
    let title: String
    let description: String
    
    // 简写名称（取前6个字符）
    var shortName: String {
        let maxLength = 6
        if title.count <= maxLength {
            return title
        } else {
            return String(title.prefix(maxLength)) + "..."
        }
    }
    
    
}

class AlbumScene: SCNScene {
    var photos: [AlbumPhoto] = []
    private var photoNodes: [SCNNode] = []
    
    override init() {
        super.init()
        setupScene()
        createSamplePhotos()
        arrangePhotosInCircle()
        addCameraAndLights()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupScene() {
        background.contents = NSColor.black
    }
    
    private func createSamplePhotos() {
        // 从本地文件夹读取媒体文件
        let mediaFiles = loadMediaFilesFromDirectory()
        
        if mediaFiles.isEmpty {
            // 如果没有找到媒体文件，使用示例数据
            photos = [
                AlbumPhoto(imageName: "photo1", title: "示例图片 1", description: "示例描述"),
                AlbumPhoto(imageName: "photo2", title: "示例图片 2", description: "示例描述"),
                AlbumPhoto(imageName: "photo3", title: "示例图片 3", description: "示例描述")
            ]
        } else {
            photos = mediaFiles
        }
    }
    
    private func loadMediaFilesFromDirectory() -> [AlbumPhoto] {
        var mediaFiles: [AlbumPhoto] = []
        
        // 获取用户图片目录
        let picturesURL = FileManager.default.urls(for: .picturesDirectory, in: .userDomainMask).first
        
        // 或者使用项目内的Resources文件夹
        let resourcesURL = Bundle.main.resourceURL
        
        let searchURL = picturesURL ?? resourcesURL
        
        guard let url = searchURL else { return [] }
        
        do {
            let fileManager = FileManager.default
            let contents = try fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil)
            
            // 支持的媒体文件格式
            let imageExtensions = ["jpg", "jpeg", "png", "gif", "bmp", "tiff"]
            let videoExtensions = ["mov", "mp4", "avi", "m4v"]
            
            for fileURL in contents {
                let fileExtension = fileURL.pathExtension.lowercased()
                
                if imageExtensions.contains(fileExtension) || videoExtensions.contains(fileExtension) {
                    let fileName = fileURL.deletingPathExtension().lastPathComponent
                    let mediaType = imageExtensions.contains(fileExtension) ? "image" : "video"
                    
                    let photo = AlbumPhoto(
                        imageName: fileURL.path,
                        title: fileName,
                        description: "\(mediaType) - \(fileExtension.uppercased())"
                    )
                    mediaFiles.append(photo)
                }
            }
        } catch {
            print("读取目录错误: \(error.localizedDescription)")
        }
        
        return mediaFiles
    }
    
    private func arrangePhotosInCircle() {
        let radius: Float = 3.0
        let count = photos.count
        
        for (index, photo) in photos.enumerated() {
            let angle = Float(index) * (2 * .pi / Float(count))
            let x = radius * cos(angle)
            let z = radius * sin(angle)
            
            let photoNode = createPhotoNode(for: photo, position: SCNVector3(x, 0, z))
            photoNode.look(at: SCNVector3(0, 0, 0))
            photoNodes.append(photoNode)
            rootNode.addChildNode(photoNode)
        }
    }
    
    private func createPhotoNode(for photo: AlbumPhoto, position: SCNVector3) -> SCNNode {
        let plane = SCNPlane(width: 2.0, height: 1.5)
        
        let material = SCNMaterial()
        
        // 检查文件扩展名来确定是图片还是视频
        let fileExtension = (photo.imageName as NSString).pathExtension.lowercased()
        let imageExtensions: Set<String> = ["jpg", "jpeg", "png", "gif", "bmp", "tiff"]
        
        if imageExtensions.contains(fileExtension) {
            // 加载图片
            if let image = NSImage(contentsOfFile: photo.imageName) {
                material.diffuse.contents = image
            } else {
                material.diffuse.contents = NSColor.blue.withAlphaComponent(0.8)
            }
        } else {
            // 视频文件 - 创建视频播放器
            material.diffuse.contents = createVideoPlayer(for: photo.imageName)
        }
        
        material.isDoubleSided = true
        
        // 使用简写名称显示
        let textGeometry = SCNText(string: photo.shortName, extrusionDepth: 0.1)
        textGeometry.font = NSFont.systemFont(ofSize: 0.2)
        
        let textNode = SCNNode(geometry: textGeometry)
        textNode.position = SCNVector3(0, -0.8, 0.01)
        
        plane.materials = [material]
        
        let photoNode = SCNNode(geometry: plane)
        photoNode.position = position
        photoNode.name = photo.id.uuidString
        
        photoNode.addChildNode(textNode)
        
        return photoNode
    }
    
    private func createVideoPlayer(for videoPath: String) -> SKScene {
        let videoURL = URL(fileURLWithPath: videoPath)
        let player = AVPlayer(url: videoURL)
        
        let videoNode = SKVideoNode(avPlayer: player)
        videoNode.size = CGSize(width: 400, height: 300)
        videoNode.position = CGPoint(x: 200, y: 150)
        
        let scene = SKScene(size: CGSize(width: 400, height: 300))
        scene.backgroundColor = .black
        scene.addChild(videoNode)
        
        player.play()
        
        return scene
    }
    
    private func addCameraAndLights() {
        // Camera
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(0, 2, 8)
        cameraNode.look(at: SCNVector3(0, 0, 0))
        rootNode.addChildNode(cameraNode)
        
        // Ambient light
        let ambientLight = SCNLight()
        ambientLight.type = .ambient
        ambientLight.color = NSColor.white.withAlphaComponent(0.3)
        let ambientNode = SCNNode()
        ambientNode.light = ambientLight
        rootNode.addChildNode(ambientNode)
        
        // Directional light
        let directionalLight = SCNLight()
        directionalLight.type = .directional
        directionalLight.color = NSColor.white
        let directionalNode = SCNNode()
        directionalNode.light = directionalLight
        directionalNode.position = SCNVector3(5, 5, 5)
        directionalNode.look(at: SCNVector3(0, 0, 0))
        rootNode.addChildNode(directionalNode)
    }
    
    func rotateAlbum(by angle: Float) {
        rootNode.runAction(SCNAction.rotateBy(x: 0, y: CGFloat(angle), z: 0, duration: 0.5))
    }
    
    func loadMediaFromFolder(_ folderPath: String) {
        // 清除现有的照片节点
        photoNodes.forEach { $0.removeFromParentNode() }
        photoNodes.removeAll()
        
        // 从指定文件夹加载媒体文件
        let folderURL = URL(fileURLWithPath: folderPath)
        do {
            let fileManager = FileManager.default
            let contents = try fileManager.contentsOfDirectory(at: folderURL, includingPropertiesForKeys: nil)
            
            // 支持的媒体文件格式
            let imageExtensions = ["jpg", "jpeg", "png", "gif", "bmp", "tiff"]
            let videoExtensions = ["mov", "mp4", "avi", "m4v"]
            
            var newPhotos: [AlbumPhoto] = []
            
            for fileURL in contents {
                let fileExtension = fileURL.pathExtension.lowercased()
                
                if imageExtensions.contains(fileExtension) || videoExtensions.contains(fileExtension) {
                    let fileName = fileURL.deletingPathExtension().lastPathComponent
                    let mediaType = imageExtensions.contains(fileExtension) ? "image" : "video"
                    
                    let photo = AlbumPhoto(
                        imageName: fileURL.path,
                        title: fileName,
                        description: "\(mediaType) - \(fileExtension.uppercased())"
                    )
                    newPhotos.append(photo)
                }
            }
            
            if !newPhotos.isEmpty {
                photos = newPhotos
                arrangePhotosInCircle()
            }
        } catch {
            print("读取文件夹错误: \(error.localizedDescription)")
        }
    }

}

struct SceneKitView: NSViewRepresentable {
    let scene: SCNScene
    
    func makeNSView(context: Context) -> SCNView {
        let scnView = SCNView()
        scnView.scene = scene
        scnView.allowsCameraControl = true
        scnView.autoenablesDefaultLighting = true
        scnView.backgroundColor = NSColor.black
        
        // 添加点击手势识别
        let clickGesture = NSClickGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleClick(_:)))
        scnView.addGestureRecognizer(clickGesture)
        
        return scnView
    }
    
    func updateNSView(_ nsView: SCNView, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        Coordinator(scene: scene)
    }
    
    class Coordinator {
        let scene: SCNScene
        var selectedNode: SCNNode?
        
        init(scene: SCNScene) {
            self.scene = scene
        }
        
        @objc func handleClick(_ gesture: NSClickGestureRecognizer) {
            guard let scnView = gesture.view as? SCNView else { return }
            
            let location = gesture.location(in: scnView)
            let hitResults = scnView.hitTest(location, options: nil)
            
            if let firstHit = hitResults.first {
                let node = firstHit.node
                
                // 如果点击的是照片节点（不是文本节点）
                if node.geometry is SCNPlane {
                    // 缩放选中的节点
                    scaleNode(node)
                    selectedNode = node
                    
                    // 在AR模式下，触发媒体选择
                    if let photoID = node.name, 
                       let photo = (scene as? AlbumScene)?.photos.first(where: { $0.id.uuidString == photoID }) {
                        // 这里需要通知ContentView显示全屏视图
                        // 由于Coordinator无法直接访问@State，我们可以使用NotificationCenter
                        NotificationCenter.default.post(name: .mediaSelected, object: photo)
                    }
                }
            }
        }
        
        func scaleNode(_ node: SCNNode) {
            // 先恢复所有节点的缩放
            scene.rootNode.childNodes.forEach { childNode in
                if childNode.geometry is SCNPlane {
                    childNode.removeAllActions()
                    childNode.runAction(SCNAction.scale(to: 1.0, duration: 0.3))
                }
            }
            
            // 放大选中的节点
            let scaleAction = SCNAction.scale(to: 1.5, duration: 0.3)
            node.runAction(scaleAction)
            
            // 3秒后自动恢复缩放
            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                node.runAction(SCNAction.scale(to: 1.0, duration: 0.3))
            }
        }
    }
}

struct ContentView: View {
    @State private var albumScene = AlbumScene()
    @State private var rotationAngle: Float = 0
    @State private var showFilePicker = false
    @State private var selectedFolder: String? = nil
    @State private var isARMode = false
    @State private var selectedMedia: AlbumPhoto? = nil
    @State private var isAutoPlaying = false
    
    var body: some View {
        VStack {
            SceneKitView(scene: albumScene)
                .frame(width: 800, height: 600)
            
            HStack(spacing: 15) {
                Button("选择文件夹") {
                    showFilePicker = true
                }
                
                Button("AR模式") {
                    isARMode.toggle()
                    if isARMode {
                        // AR模式开启时，从随机图片开始播放
                        isAutoPlaying = true
                        startARSlideShowFromRandom()
                    } else {
                        // AR模式关闭时，停止自动播放
                        isAutoPlaying = false
                    }
                }
                
                if isARMode {
                    Button("停止自动播放") {
                        isAutoPlaying = false
                    }
                }
                
                Button("随机缩放图片") {
                    scaleRandomPhoto()
                }
                
                Button("左旋转") {
                    albumScene.rotateAlbum(by: .pi / 4)
                }
                
                Button("右旋转") {
                    albumScene.rotateAlbum(by: -.pi / 4)
                }
            }
            .padding()
            
            if let folder = selectedFolder {
                Text("当前文件夹: \(folder)")
                    .font(.caption)
                    .foregroundColor(.gray)
            }
            
            if isARMode {
                Text("AR模式已开启 - 点击照片查看全屏")
                    .font(.caption)
                    .foregroundColor(.green)
                    .padding()
            }
        }
        .sheet(isPresented: $showFilePicker) {
            FolderPicker(selectedFolder: $selectedFolder) { folderPath in
                if let path = folderPath {
                    // 重新加载指定文件夹的媒体文件
                    albumScene.loadMediaFromFolder(path)
                }
            }
        }
        .sheet(item: $selectedMedia) { media in
            MediaDetailView(media: media, isPresented: $selectedMedia)
        }
        .onReceive(NotificationCenter.default.publisher(for: .mediaSelected)) { notification in
            if let photo = notification.object as? AlbumPhoto {
                handleMediaSelection(photo)
            }
        }
        .onReceive(NotificationCenter.default.publisher(for: .videoPlaybackCompleted)) { _ in
            // 视频播放完成后自动关闭
            selectedMedia = nil
            // 播放下下一个媒体
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                playNextARMedia()
            }
        }
        .onReceive(NotificationCenter.default.publisher(for: .startARSlideShow)) { _ in
            // 处理AR幻灯片播放
            startARSlideShow()
        }
    }
    
    private func scaleRandomPhoto() {
        // 随机选择一张照片的节点
        let photoNodes = albumScene.rootNode.childNodes.filter { $0.geometry is SCNPlane }
        if let randomPhotoNode = photoNodes.randomElement() {
            // 创建临时coordinator来执行缩放
            let coordinator = SceneKitView.Coordinator(scene: albumScene)
            coordinator.scaleNode(randomPhotoNode)
            
            // 如果是AR模式，显示全屏视图并开始自动播放
            if isARMode, let photoID = randomPhotoNode.name,
               let photo = albumScene.photos.first(where: { $0.id.uuidString == photoID }) {
                selectedMedia = photo
                
                // 如果是图片，发送通知让ContentView处理自动播放
                if !photo.imageName.hasSuffix(".mov") && !photo.imageName.hasSuffix(".mp4") &&
                   !photo.imageName.hasSuffix(".avi") && !photo.imageName.hasSuffix(".m4v") {
                    NotificationCenter.default.post(name: .startARSlideShow, object: nil)
                }
            }
        }
    }
    
    private func handleMediaSelection(_ photo: AlbumPhoto) {
        if isARMode {
            selectedMedia = photo
            
            // 如果是图片，发送通知让ContentView处理自动播放
            if !photo.imageName.hasSuffix(".mov") && !photo.imageName.hasSuffix(".mp4") &&
               !photo.imageName.hasSuffix(".avi") && !photo.imageName.hasSuffix(".m4v") {
                NotificationCenter.default.post(name: .startARSlideShow, object: nil)
            }
        }
    }
    
    private func startARSlideShow() {
        // 只有在自动播放模式下才继续播放
        guard isAutoPlaying else { return }
        
        // 2秒后自动关闭当前媒体并播放下一个
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            selectedMedia = nil
            
            // 延迟一下再播放下一个，避免太快
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                self.playNextARMedia()
            }
        }
    }
    
    private func startARSlideShowFromRandom() {
        // 从随机图片开始播放
        if let randomPhoto = albumScene.photos.randomElement() {
            selectedMedia = randomPhoto
            
           // 如果是图片，2秒后自动播放下一个
            if !randomPhoto.imageName.hasSuffix(".mov") && !randomPhoto.imageName.hasSuffix(".mp4") &&
               !randomPhoto.imageName.hasSuffix(".avi") && !randomPhoto.imageName.hasSuffix(".m4v") {
                startARSlideShow()
            }
        }
    }
    
    private func playNextARMedia() {
        guard isARMode && isAutoPlaying else { return }
        
        // 随机选择一张图片播放
        if let randomPhoto = albumScene.photos.randomElement() {
            selectedMedia = randomPhoto
            
            // 如果是图片，2秒后自动播放下一个
            if !selectedMedia!.imageName.hasSuffix(".mov") && !selectedMedia!.imageName.hasSuffix(".mp4") &&
               !selectedMedia!.imageName.hasSuffix(".avi") && !selectedMedia!.imageName.hasSuffix(".m4v") {
                startARSlideShow()
            }
        }
    }
    
    struct FolderPicker: View {
        @Binding var selectedFolder: String?
        var onFolderSelected: (String?) -> Void
        @Environment(\.presentationMode) var presentationMode
        
        var body: some View {
            VStack {
                Text("选择包含图片或视频的文件夹")
                    .font(.headline)
                    .padding()
                
                Button("打开文件夹选择器") {
                    let openPanel = NSOpenPanel()
                    openPanel.title = "选择媒体文件夹"
                    openPanel.showsResizeIndicator = true
                    openPanel.showsHiddenFiles = false
                    openPanel.canChooseFiles = false
                    openPanel.canChooseDirectories = true
                    openPanel.canCreateDirectories = true
                    openPanel.allowsMultipleSelection = false
                    
                    if openPanel.runModal() == .OK {
                        if let url = openPanel.url {
                            selectedFolder = url.path
                            onFolderSelected(url.path)
                        }
                    }
                    presentationMode.wrappedValue.dismiss()
                }
                .padding()
                
                Button("取消") {
                    presentationMode.wrappedValue.dismiss()
                }
                .padding()
            }
            .frame(width: 300, height: 200)
        }
    }
}
